package cn.iot.netty;

import cn.iot.common.utils.SpringUtils;
import cn.iot.netty.service.SendInstructsServiceImpl;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.InetSocketAddress;


@Slf4j
@Component
public class NettyServerHandler extends ChannelInboundHandlerAdapter {

    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    public static ChannelGroup getChannelGroup() {
        return channelGroup;
    }

    private static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    private static final SendInstructsServiceImpl sis = SpringUtils.getBean("sendInstructsService");

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        log.info("有客户端{}上线", channel.remoteAddress());
        // 将当前channel加入到channelGroup
        channelGroup.add(channel);
    }

    /**
     * 从客户端收到新的数据时，这个方法会在收到消息时被调用
     *
     * @param ctx
     * @param msg
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception, IOException {
        String str = (String) msg;
        log.info("channelRead:read msg:" + msg);
        //将收到的消息发送给回调处理方法
        InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
        String clientIp = insocket.getAddress().getHostAddress();
        sis.callbackInstructResultMsg(clientIp, str);
    }

    private void writeMessage(ChannelHandlerContext ctx, byte[] obj) {
        ByteBuf bufff = Unpooled.buffer();//netty需要用ByteBuf传输
        bufff.writeBytes(obj);//对接需要16进制

        ctx.writeAndFlush(bufff).addListener(new ChannelFutureListener() { //获取当前的handle
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                StringBuilder sb = new StringBuilder("");

                if (future.isSuccess()) {

                    log.info(sb.toString() + "回写成功.");
                } else {
                    log.error(sb.toString() + "回写失败.");
                }
            }
        });
    }

    /**
     * 从客户端收到新的数据、读取完成时调用
     *
     * @param ctx
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws IOException {
        log.info("channelReadComplete");

        ctx.flush();
    }


}
